package DigiJoe;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import javax.imageio.ImageIO;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class GuiView extends JFrame {

    private JTextField statusBar;
    private MyCanvas drawingCanvas;
    private ArrayList<Integer[]> wires;
    private HashMap<Integer, ComponentImage> componentImageList = new HashMap<Integer, ComponentImage>();
    private HashMap<ElementType, BufferedImage[]> Images = new HashMap<ElementType, BufferedImage[]>();
    private GuiController controller;

    //Componensek, illetve azoknak a be és kimeneti portjainak száma
    public GuiView( GuiController controller) {
        super("DIGI joez");
        this.controller = controller;
        initComponents();
        LoadImages();                
    }

    //update the data
    public void initWithData(ArrayList<ElementType> components, ArrayList<Integer> inPorts, ArrayList<Integer> outPorts, ArrayList<Integer[]> wires)
    {
        componentImageList.clear();
        this.wires = wires;
        
        //Component image-ek létrehozása
        //i a komponens sorszama
        //csinalunk soronkent 8 oszlopot, minden masodik oszlopba kerul elem
        for (int i = 0; i < components.size(); i++) {
            Coordinate c = new Coordinate((i % 5) * 200, (i / 5) * 200);
            switch (components.get(i)) {
                case Switch:
                    componentImageList.put(componentImageList.size(), new ComponentImage(
                            Images.get(ElementType.Switch)[0], Images.get(ElementType.Switch)[1],
                            c, i,
                            inPorts.get(i), outPorts.get(i)));
                    break;
                case ANDGate:
                    componentImageList.put(componentImageList.size(), new ComponentImage(
                            Images.get(ElementType.ANDGate)[0], Images.get(ElementType.ANDGate)[1],
                            c, i,
                            inPorts.get(i), outPorts.get(i)));
                    break;
                case Composit:
                    componentImageList.put(componentImageList.size(), new ComponentImage(
                            Images.get(ElementType.Composit)[0], Images.get(ElementType.Composit)[1],
                            c, i,
                            inPorts.get(i), outPorts.get(i)));
                    break;
                case Generator:
                    componentImageList.put(componentImageList.size(), new ComponentImage(
                            Images.get(ElementType.Generator)[0], Images.get(ElementType.Generator)[1],
                            c, i,
                            inPorts.get(i), outPorts.get(i)));
                    break;
                case Inverter:
                    componentImageList.put(componentImageList.size(), new ComponentImage(
                            Images.get(ElementType.Inverter)[0], Images.get(ElementType.Inverter)[1],
                            c, i,
                            inPorts.get(i), outPorts.get(i)));
                    break;
                case Led:
                    componentImageList.put(componentImageList.size(), new ComponentImage(
                            Images.get(ElementType.Led)[0], Images.get(ElementType.Led)[1],
                            c, i,
                            inPorts.get(i), outPorts.get(i)));
                    break;
                case ORGate:
                    componentImageList.put(componentImageList.size(), new ComponentImage(
                            Images.get(ElementType.ORGate)[0], Images.get(ElementType.ORGate)[1],
                            c, i,
                            inPorts.get(i), outPorts.get(i)));
                    break;
                case Oscilloscope:
                    componentImageList.put(componentImageList.size(), new ComponentImage(
                            Images.get(ElementType.Oscilloscope)[0], Images.get(ElementType.Oscilloscope)[1],
                            c, i,
                            inPorts.get(i), outPorts.get(i)));
                    break;
            }
        }
    }
    
    //Load On and Off images
    private void LoadImages() {
        //TODO: képnevek
        try {
            Images.put(ElementType.Led, new BufferedImage[]{
                        ImageIO.read(new File("images/ledon.jpg")),//on
                        ImageIO.read(new File("images/ledoff.jpg"))//off
                    });
            Images.put(ElementType.ANDGate, new BufferedImage[]{
                        ImageIO.read(new File("images/ANDGate.jpg")),
                        ImageIO.read(new File("images/ANDGate.jpg"))
                    });
            Images.put(ElementType.Composit, new BufferedImage[]{
                        ImageIO.read(new File("images/composit.jpg")),
                        ImageIO.read(new File("images/composit.jpg"))
                    });
            Images.put(ElementType.Generator, new BufferedImage[]{
                        ImageIO.read(new File("images/generator.jpg")),
                        ImageIO.read(new File("images/generator.jpg"))
                    });
            Images.put(ElementType.Inverter, new BufferedImage[]{
                        ImageIO.read(new File("images/inverter.jpg")),
                        ImageIO.read(new File("images/inverter.jpg"))
                    });
            Images.put(ElementType.ORGate, new BufferedImage[]{
                        ImageIO.read(new File("images/ORGate.jpg")),
                        ImageIO.read(new File("images/ORGate.jpg"))
                    });
            Images.put(ElementType.Oscilloscope, new BufferedImage[]{
                        ImageIO.read(new File("images/oscilloscope.jpg")),
                        ImageIO.read(new File("images/oscilloscope.jpg"))
                    });
            Images.put(ElementType.Switch, new BufferedImage[]{
                        ImageIO.read(new File("images/switchon.jpg")),
                        ImageIO.read(new File("images/switchoff.jpg"))
                    });
        } catch (IOException e) {
        }
    }

    //Státusz kiiratása
    public void SetStatus(String text) {
        statusBar.setText(text);
    }

    //Komponens épének visszaadása id alapján
    public ComponentImage getComponentImage(int id) {
        return componentImageList.get(id);
    }

    //Koordináták alapján a klikkelt komponens id-jének visszaadása
    public int GetClickedComponent(int X, int Y) {
        // !!!!!! mouseclick egesz ablakos koordinatat ad
        for(int i = 0; i < componentImageList.size(); i++){
            if(componentImageList.get(i).isInside(X, Y))
                return i;
        }
        return -1;
    }

    //Dialog ablak
    public void displayDialog(String text) {
        JOptionPane.showMessageDialog(this, text);
    }

    //Kép kirajzolása
    public void Draw() {
        drawingCanvas.repaint();
    }

    private void initComponents() {
        //create menubar
        JMenuBar menuBar = new JMenuBar();
        
        //create menu
        JMenu menu = new JMenu("File");
        
        //add it to the menubar
        menuBar.add(menu);
        
        //create menuitems
        JMenuItem item1 = new JMenuItem("Load network");
        item1.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                controller.LoadNetwork();
            }
        });
        menu.add(item1);
        JMenuItem item2 = new JMenuItem("Reset network");
        item2.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                controller.ResetNetwork();
            }
        });
        menu.add(item2);
        JMenuItem item3 = new JMenuItem("Exit");
        item3.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                controller.Exit();
            }
        });
        menu.add(item3);
        
        //add the menubar
        this.setJMenuBar(menuBar);
        
        //borderlayout
        this.setLayout(new BorderLayout());
        
        //button panel
        JPanel buttonPane = new JPanel();
        buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.LINE_AXIS));
        
        //glue so the button sticks to the right
        buttonPane.add(Box.createHorizontalGlue());
        
        //button
        JButton bt = new JButton("Step");
        bt.setPreferredSize(new Dimension(150, 30));
        bt.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                controller.StepSimulation();
            }
        });
        
        //add it to the panel
        buttonPane.add(bt);
        
        //main drawing area
        JPanel drawingare = new JPanel();
        
        //rigid area for drawing
        //Canvas box = new Canvas(null);
        //box.setPreferredSize(new Dimension(950, 700));
                
        //add it to the panel
        drawingCanvas = new MyCanvas(this);
        drawingare.add(drawingCanvas);
        
        //add mouse listener
        drawingCanvas.addMouseListener(controller);
        
        //lowerpanel
        JPanel statusPane = new JPanel();
        statusPane.setLayout(new BoxLayout(statusPane, BoxLayout.LINE_AXIS));
        
        //add statustext
        statusBar = new JTextField();
        statusBar.setEnabled(false);
        statusBar.setText("Status bar");
        statusPane.add(statusBar);
        
        this.add(buttonPane, BorderLayout.PAGE_START);
        this.add(drawingare, BorderLayout.CENTER);
        this.add(statusPane, BorderLayout.PAGE_END);
    }
    
    public HashMap<Integer, ComponentImage> getComponentImageList()
    {
        return componentImageList;
    }
    
    public ArrayList<Integer[]> getWires()
    {
        return wires;
    }
    
    public boolean isLoaded()
    {
        return controller.getLoaded();
    }
}
